home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 7
/
FM Towns Free Software Collection 7.iso
/
ms_dos
/
fplink
/
fplinki.c
< prev
next >
Wrap
Text File
|
1993-11-30
|
17KB
|
676 lines
/* PC98<->IBM<->FMR ファイル転送 for IBM Copyright (c) E.Suto , 1992-1993 */
/* 修正履歴 Ver 0.00 1992/06/22 試作品 */
/* Ver 0.10 1992/06/23 近所公開版 */
/* Ver 0.20 1992/06/26 簡易サーバーモード追加,共用ドライブ対応*/
/* Ver 0.21 1992/06/28 リモートコマンド追加 */
/* Ver 0.30 1992/06/30 TIMEOUT()改造,オプション統合,速度表示 */
/* Ver 0.31 1992/07/03 簡易サーバーを出来るだけ止めないよう */
/* Ver 0.32 1992/07/03 速度表示の0割り算ガード(超手抜き) */
/* Ver 0.33 1992/07/06 . の消し方変更 */
/* Ver 0.34 1992/07/10 受信ファイルがルートに行ってしまうバグ修正 */
/* Ver 0.35 1992/11/17 RS232Cのバグ修正(98版のみ) */
/* Ver 0.36 1992/11/17 ちょっと高速化(^^; */
/* Ver 0.37 1992/11/18 タイマ値最適化 */
/* Ver 0.38 1992/11/18 送信ファイル名バグ修正 */
/* Ver 0.39 1992/11/18 サーバーバグ修正 */
/* Ver 0.41 1993/02/04 inpのwaitを#defineに */
/* Ver 0.42 1993/02/04 ソースをちょっと統合(^^; */
/* Ver 1.00 1993/ 2/ 3 失敗時にタイムアウトしない */
/* Ver 1.01 1993/ 2/ 4 コマンド受信処理でタイムアウトしない */
/* Ver 3.00 1993/ 3/25 PC98/FMR版と統合 */
/* Ver 3.01 1993/ 4/ 1 低レベルI/Oテスト版 */
/* Ver 3.02 1993/ 5/31 コマンド”判定バグ修正 */
/* Ver 3.03 1993/ 6/29 接続失敗に対する修正 */
/* Ver 3.03E 1993/ 6/30 英語のような物にメッセージ変更 */
/* Ver 3.04 1993/ 7/ 8 接続失敗に対するさらに修正 */
/* Ver 3.05 1993/ 7/15 正常終了時exit(0)に */
/* Ver 3.06 1993/ 8/ 2 サーバータイムアウト対策 */
/* Ver 3.07 1993/ 8/ 2 対98/TOWNSの受信高速化? */
/* Ver 3.08 1993/ 8/ 2 対98/TOWNSの受信高速化-II */
/* Ver 3.09 1993/ 8/15 IBMのタイムアウト時間短縮 */
#define _IBM
#include "fplink.h"
static unsigned char send_mc ; /* モデムコントロール値 */
static unsigned char send_lc ; /* ラインコントロール値 */
static unsigned int rs_line_c ; /* ラインコントロール */
static unsigned int rs_line_s ; /* ラインステータス */
static unsigned int rs_int ; /* 割り込みコントロール */
static unsigned int rs_in ; /* モデムステータス */
static unsigned int rs_out ; /* モデムコントロール */
static unsigned char rs_int_data ; /* 割り込みデータ */
static unsigned char data1_7[8]= {0x00,0x01,0x00,0x01,0x02,0x03,0x02,0x03} ;
static unsigned char data2_7[8]= {0x00,0x00,0x40,0x40,0x00,0x00,0x40,0x40} ;
static unsigned char stat_7[8] = {0x00,0x40,0x80,0xc0,0x10,0x50,0x90,0xd0} ;
static unsigned char _7data[256] ;
void main(int argc,char *argv[])
{
int i , j , k , l , m ;
unsigned char *c ;
debug = 0 ;
mode = -1 ;
rs_out = 0x03fc ;
rs_line_c = 0x03fb ;
rs_line_s = 0x03fd ;
rs_in = 0x03fe ;
rs_int = 0x03f9 ;
_7data[0x00]= 0 ;
_7data[0x40]= 1 ;
_7data[0x80]= 2 ;
_7data[0xc0]= 3 ;
_7data[0x10]= 4 ;
_7data[0x50]= 5 ;
_7data[0x90]= 6 ;
_7data[0xd0]= 7 ;
strcpy( command , "" ) ;
strcpy( path , "" ) ;
/* コピーライト表示 */
copyright() ;
/* 割り込み処理定義 */
signal( SIGINT , sig_out ) ;
/* オプションチェック */
if( argc < 2 ) {
usage() ;
exit( 0 ) ;
}
else {
k = l = 0 ;
for( i=1 ; i<argc ; i++ ) {
c = argv[i] ;
if( *c == '-' || *c == '/' ) {
switch( *++c ) {
case '?' :
usage();
exit( 0 );
case 'i' :
case 'I' :
debug = -1 ;
break ;
case 'R' :
case 'r' :
if( k ) mode = 4 ;
else mode = 1 ;
break ;
case 'S' :
case 's' :
mode = 0 ;
break ;
case 'Z' :
case 'z' :
mode = 2 ;
break ;
case 'C' :
case 'c' :
mode = 5 ;
c++ ;
strcpy( command , c ) ;
if( command[0] == '"' ) {
for( ; i < argc ; ) {
if( ( strlen( command ) > 1 )
&& ( command[strlen( command ) - 1 ] == '"' ) )
break ;
i++ ;
strcat( command , " " ) ;
strcat( command , argv[i] ) ;
}
}
break ;
case 'X' :
case 'x' :
c++ ;
l = -1 ;
strcpy( path , c ) ;
break ;
case 'P' :
case 'p' :
c++ ;
if( *c != ' ' ) {
if( sscanf( c , "%d" , &j ) == EOF )
goto perr ;
if( j == 0 ) {
rs_out = 0x03fc ;
rs_line_c = 0x03fb ;
rs_line_s = 0x03fd ;
rs_in = 0x03fe ;
rs_int = 0x03f9 ;
}
else {
if( j == 1 ) {
rs_out = 0x02fc ;
rs_line_c = 0x02fb ;
rs_line_s = 0x02fd ;
rs_in = 0x02fe ;
rs_int = 0x02f9 ;
}
else goto perr ;
}
}
else {
rs_out = 0x03fc ;
rs_line_c = 0x03fb ;
rs_line_s = 0x03fd ;
rs_in = 0x03fe ;
rs_int = 0x03f9 ;
}
break ;
default :
perr: printf( "A wrong parameter is specified. whether two file names or more are specified.(%s)\n" , argv[i] ) ;
usage() ;
exit( -1 ) ;
}
}
else {
if( mode == 5 ) {
if( strlen( command ) > 0 ) goto perr ;
strcpy( command , c ) ;
if( command[0] == '"' ) {
for( ; i < argc ; ) {
if( ( strlen( command ) > 1 )
&& ( command[strlen( command ) - 1 ] == '"' ) )
break ;
i++ ;
strcat( command , " " ) ;
strcat( command , argv[i] ) ;
}
}
else {
for( ; i < argc ; ) {
i++ ;
if( ( *(argv[i]) == '-' ) || ( *(argv[i]) == '/' ) )
break ;
strcat( command , " " ) ;
strcat( command , argv[i] ) ;
}
}
}
else {
if( k ) goto perr ;
strcpy( name , argv[i] ) ;
k = -1 ;
if( mode == 1 ) mode = 4 ;
}
}
}
}
/* オプションの関連チェック */
if( mode == -1 ) {
printf( "Please specify -r, -s, -z or -c.\n" ) ;
usage() ;
exit( -1 ) ;
}
if( !( k ) && ( mode == 0 ) ) {
printf( "When -s is specified, the file name cannot be omitted.\n" ) ;
usage() ;
exit( -1 ) ;
}
if( l && ( mode != 0 ) ) {
printf( "-x cannot be specified besides -s is specified.\n" ) ;
usage() ;
exit( -1 ) ;
}
if( mode == 5 ) {
strcpy( buffer , command ) ;
if( buffer[0] == '"' ) {
m = strlen( buffer ) ;
if( buffer[m-1] != '"' ) {
printf( "\" by which the end of the command is shown is insufficient.(%s)\n",buffer ) ;
usage() ;
exit( -1 ) ;
}
buffer[m-1] = 0x00 ;
strcpy( command , ( buffer + 1 ) ) ;
}
if( strlen( command ) == 0 ) {
printf( "Please specify a remote command following -c .\n" ) ;
usage() ;
exit( -1 ) ;
}
if( strlen( command ) > 114 ) {
printf( "The command is too long though it is not .\n" ) ;
printf( "Please make to 114 characters or less.\n" ) ;
usage() ;
exit( -1 ) ;
}
}
/* タイムアウト値設定 */
timeset() ;
/* 回線の初期化 */
rs_init = rs_set ;
rs_init() ;
rs_init = rs_reset ;
/* 送受信処理へ */
switch( mode ) {
case 0 : /* 送信処理 */
connect_s() ;
fp_send() ;
break ;
case 1 : /* 受信処理 */
connect_r() ;
fp_receive0() ;
fp_receive() ;
break ;
case 2 : /* サーバー処理 */
fp_server() ;
break ;
case 4 : /* サーバーからの受信処理 */
connect_s() ;
fp_file() ;
fp_receive0() ;
fp_receive() ;
break ;
case 5 : /* リモートコマンド処理 */
connect_s() ;
fp_command() ;
break ;
}
/* 後始末 */
printf( "The telephotography processing was done.\n" ) ;
rs_init() ;
exit( 0 ) ;
}
/* 8250の初期化 */
void rs_set()
{
/* 割り込みの禁止 */
di() ;
/* ラインステータスレジスタ */
inp( rs_line_s ) ;
/* モデムコントロールレジスタ */
send_mc = ( inp( rs_out ) & 0x1c ) ;
outp( rs_out , send_mc ) ;
/* ラインコントロールレジスタ */
send_lc = ( inp( rs_line_c ) & 0xbf ) ;
outp( rs_line_c , ( send_lc & 0x7f ) ) ;
/* 割り込みの禁止 */
rs_int_data = inp( rs_int ) & 0x0f ;
outp( rs_int , 0x00 ) ;
/* 割り込み許可 */
ei() ;
}
/* 8250の初期化 */
void rs_reset()
{
/* 割り込みの禁止 */
di() ;
/* ラインステータスレジスタ */
inp( rs_line_s ) ;
/* モデムコントロールレジスタ */
outp( rs_out , send_mc ) ;
/* ラインコントロールレジスタ */
outp( rs_line_c , ( send_lc & 0x7f ) ) ;
/* 割り込みの許可 */
outp( rs_int , rs_int_data ) ;
/* ラインコントロールレジスタ */
outp( rs_line_c , send_lc ) ;
/* 割り込み許可 */
ei() ;
}
/* 接続確認待ち(送信型)*/
int connect_s()
{
unsigned char stat1,stat2,stat0 ;
long j ;
/* 接続確認 */
palawait = PALAWAIT_I ;
if( mode != 2 ) printf( "It is connected waiting.\n" ) ;
outp( rs_line_c , send_lc ) ;
outp( rs_out , send_mc | 0x01 ) ; /* ずーと待つからsendは使わない */
stat0 = 0x00 ;
stat1 = 0x40 ;
stat2 = 0xd0 ;
for( j = 0 ; j < palawait*20 ; j++ ) ;
con_init1:
while( ( inp( rs_in ) & 0xd0 ) != stat1 ) {
printf( "*\r" ) ;
if( kbhit() ) {
if( getch() == 0x1b ) sig_out() ;
}
}
for( j = 0 ; j < palawait*30 ; j++ ) ;
if( ( inp( rs_in ) & 0xd0 ) != stat1 ) goto con_init1 ;
outp( rs_line_c , send_lc | 0x40 ) ;
outp( rs_out , send_mc | 0x03 ) ; /* ずーと待つからsendは使わない */
con_init2:
for( j = 0 ; j < palawait*30 ; j++ ) ;
while( ( inp( rs_in ) & 0xd0 ) != stat2 ) {
printf( "*\r" ) ;
if( kbhit() ) {
if( getch() == 0x1b ) sig_out() ;
}
if( ( inp( rs_in ) & 0xd0 ) == stat0 ) goto con_init1 ;
}
if( ( inp( rs_in ) & 0xd0 ) == stat0 ) goto con_init1 ;
if( ( inp( rs_in ) & 0xd0 ) == stat1 ) goto con_init1 ;
for( j = 0 ; j < palawait*30 ; j++ ) ;
if( ( inp( rs_in ) & 0xd0 ) != stat2 ) goto con_init2 ;
old_send = old_receive = 7 ;
buffer[0] = 0xe4 ; /* このへんの文字は何でも良い(^^; */
if( send_( 1 , buffer ) ) {
if( mode == 2 ) return( -1 ) ;
else timeout() ;
}
if( debug ) printf( "Type connection transmission OK.\n" ) ;
/* 機種情報交換 */
buffer[0] = 'I' ; /* 私はIBMどす(^^; */
if( send_( 1 , buffer ) ) {
if( mode == 2 ) return( -1 ) ;
else timeout() ;
}
if( receive_( 1 , buffer ) ) {
if( mode == 2 ) return( -1 ) ;
timeout() ;
}
switch( buffer[0] ) {
case 'I' :
palawait = PALAWAIT_I ;
if( debug ) printf( "The opponent is IBM.\n" ) ;
break ;
case 'P' :
palawait = PALAWAIT_P + 1 ;
if( debug ) printf( "The opponent is PC98 or FMR.\n" ) ;
break ;
default :
printf( "The error occurred by the opponent confirmation processing.\n" ) ;
if( mode == 2 ) return( -1 ) ;
rs_init() ;
exit( -1 ) ;
}
return( 0 ) ;
}
/* 接続確認待ち(受信型)*/
int connect_r()
{
unsigned char stat1,stat2 ;
long j ;
/* 接続確認 */
palawait = PALAWAIT_I ;
if( mode != 2 ) printf( "It is connected waiting.\n" ) ;
outp( rs_line_c , send_lc ) ;
outp( rs_out , send_mc ) ; /* 状態戻し */
stat1 = 0x40 ;
stat2 = 0xd0 ;
for( j = 0 ; j < palawait*30 ; j++ ) ;
con_init3:
while( ( inp( rs_in ) & 0xd0 ) != stat1 ) {
printf( "*\r" ) ;
if( kbhit() ) {
if( getch() == 0x1b ) sig_out() ;
}
if( ( inp( rs_in ) & 0xd0 ) == stat2 ) break ;
}
for( j = 0 ; j < palawait*10 ; j++ ) ;
if( ( inp( rs_in ) & 0xd0 ) != stat1 ) goto con_init3 ;
outp( rs_line_c , send_lc ) ;
outp( rs_out , send_mc | 0x01 ) ; /* ずーと待つからsendは使わない */
for( j = 0 ; j < palawait*30 ; j++ ) ;
con_init4:
while( ( inp( rs_in ) & 0xd0 ) != stat2 ) {
printf( "*\r" ) ;
if( kbhit() ) {
if( getch() == 0x1b ) sig_out() ;
}
}
for( j = 0 ; j < palawait*10 ; j++ ) ;
if( ( inp( rs_in ) & 0xd0 ) != stat2 ) goto con_init4 ;
outp( rs_line_c , send_lc | 0x40 ) ;
outp( rs_out , send_mc | 0x03 ) ; /* ずーと待つからsendは使わない */
for( j = 0 ; j < palawait*30 ; j++ ) ;
old_send = old_receive = 7 ;
if( receive_( 1 , buffer ) ) {
if( mode == 2 ) return( -1 ) ;
timeout() ;
}
if( buffer[0] != 0xe4 ) { /* このへんの文字は送信側に合わせる */
printf( "The error occurred by connected confirmation processing.\n" ) ;
if( mode == 2 ) return( -1 ) ;
rs_init() ;
exit( -1 ) ;
}
if( debug ) printf( "Reception type connection OK.\n" ) ;
/* 機種情報交換 */
if( receive_( 1 , buffer ) ) {
if( mode == 2 ) return( -1 ) ;
timeout() ;
}
switch( buffer[0] ) {
case 'I' :
palawait = PALAWAIT_I ;
if( debug ) printf( "The opponent is IBM.\n" ) ;
break ;
case 'P' :
palawait = PALAWAIT_P + 1 ;
if( debug ) printf( "The opponent is PC98 or FMR.\n" ) ;
break ;
default :
printf( "The error occurred by the opponent confirmation processing.\n" ) ;
if( mode == 2 ) return( -1 ) ;
rs_init() ;
exit( -1 ) ;
}
buffer[0] = 'I' ; /* 私はIBMどす(^^; */
if( send_( 1 , buffer ) ) {
if( mode == 2 ) return( -1 ) ;
else timeout() ;
}
if( debug ) printf( "Model information transmission OK.\n" ) ;
return( 0 ) ;
}
/* 回線送信処理 IBM */
int send_( int l , unsigned char *b )
{
int i ;
long k,j ;
unsigned char stat0,stat1,n,data1,data2 ;
/* 受信>送信保証 */
for( j = 0 ; j < palawait ; j++ ) ;
/* 1バイトを3つに区切って3ビット毎に送信 */
for( i = 0 ; i < l ; i++ ) {
/* 割り込み禁止 */
di() ;
/* 一個目(^^; */
old_send = n = ( old_send + rem_7[*b] + 1u ) % 8u ;
stat0 = stat_7[n] ;
data1 = send_mc | data1_7[n] ;
data2 = send_lc | data2_7[n] ;
outp( rs_out , data1 ) ;
outp( rs_line_c , data2 ) ;
/* 二個目(^^; */
old_send = n = ( old_send + rem_7[div_7[*b]] + 1u ) % 8u ;
stat1 = stat_7[n] ;
for( k = timeout1 ; ( ( inp( rs_in ) ) & 0xd0 ) != stat0
; k-- ) {
if( !( k ) ) {
ei() ;
return( -1 ) ;
}
}
data1 = send_mc | data1_7[n] ;
data2 = send_lc | data2_7[n] ;
outp( rs_out , data1 ) ;
outp( rs_line_c , data2 ) ;
/* 三個目(^^; */
old_send = n = ( old_send + div_49[*b] + 1u ) % 8u ;
stat0 = stat_7[n] ;
for( k = timeout1 ; ( ( inp( rs_in ) ) & 0xd0 ) != stat1
; k-- ) {
if( !( k ) ) {
ei() ;
return( -1 ) ;
}
}
data1 = send_mc | data1_7[n] ;
data2 = send_lc | data2_7[n] ;
outp( rs_out , data1 ) ;
outp( rs_line_c , data2 ) ;
for( k = timeout1 ; ( ( inp( rs_in ) ) & 0xd0 ) != stat0
; k-- ) {
if( !( k ) ) {
ei() ;
return( -1 ) ;
}
}
/* 次のバイト処理へ */
b++ ;
/* 割り込み許可 */
ei() ;
}
old_receive = old_send ;
return( 0 ) ;
}
/* 回線受信処理 IBM */
int receive_( int l , unsigned char *b )
{
int i , j ;
long k ;
unsigned char stat,data,data1,data2,stat0 ;
/* 3ビットを3つ受信で1バイト */
for( i = 0 ; i < l ; i++ ) {
/* 割り込み禁止 */
di() ;
/* 一個目受信(^^; */
stat0 = stat_7[old_receive] ;
for( k = timeout1 ; ( inp( rs_in ) & 0xd0 ) == stat0 ; k-- ) {
if( !( k ) ) {
ei() ;
return( -1 ) ;
}
}
for( j = 0 ; j < palawait ; j++ ) ;
stat = inp( rs_in ) & 0xd0 ;
data = _7data[stat] ;
if( data < old_receive ) data += 8u ;
*b = data - old_receive - 1u ;
old_receive = _7data[stat] ;
data1 = send_mc | data1_7[old_receive] ;
data2 = send_lc | data2_7[old_receive] ;
outp( rs_out , data1 ) ;
outp( rs_line_c , data2 ) ;
/* 二個目受信(^^; */
stat0 = stat_7[old_receive] ;
for( k = timeout1 ; ( inp( rs_in ) & 0xd0 ) == stat0 ; k-- ) {
if( !( k ) ) {
ei() ;
return( -1 ) ;
}
}
for( j = 0 ; j < palawait ; j++ ) ;
stat = inp( rs_in ) & 0xd0 ;
data = _7data[stat] ;
if( data < old_receive ) data += 8u ;
*b += mul_7[data - old_receive - 1u] ;
old_receive = _7data[stat] ;
data1 = send_mc | data1_7[old_receive] ;
data2 = send_lc | data2_7[old_receive] ;
outp( rs_out , data1 ) ;
outp( rs_line_c , data2 ) ;
/* 三個目受信(^^; */
stat0 = stat_7[old_receive] ;
for( k = timeout1 ; ( inp( rs_in ) & 0xd0 ) == stat0 ; k-- ) {
if( !( k ) ) {
ei() ;
return( -1 ) ;
}
}
for( j = 0 ; j < palawait ; j++ ) ;
stat = inp( rs_in ) & 0xd0 ;
data = _7data[stat] ;
if( data < old_receive ) data += 8u ;
*b += mul_49[data - old_receive - 1u] ;
old_receive = _7data[stat] ;
data1 = send_mc | data1_7[old_receive] ;
data2 = send_lc | data2_7[old_receive] ;
outp( rs_out , data1 ) ;
outp( rs_line_c , data2 ) ;
/* 次のバイト処理へ */
b++ ;
/* 割り込み許可 */
ei() ;
}
old_send = old_receive ;
return( 0 ) ;
}
/* コピーライト表示 */
void copyright()
{
printf(
"IBM=98=FMR File transmitter for IBM Ver 3.09, Copyright (C) E.Suto , 1992-1993\n"
) ;
}
/* 使い方表示 */
void usage()
{
printf( "Direction : FPLINKI [options] [file-name]\n" ) ;
printf( "Options -s : File transmission(file-name)\n" ) ;
printf( " -r : File reception\n" ) ;
printf( " -z : Server mode\n" ) ;
printf( " -c command : A remote command is transmitted to the server.\n" ) ;
printf( " -x[path_name] : Storage path name in -s\n" ) ;
printf( " -p : Port number[0/1] default:0\n" ) ;
printf( " -i : Detailed information display\n" ) ;
}